package com.wsm.common.exception;

import com.wsm.common.domain.LogDO;
import com.wsm.common.enums.Constant;
import com.wsm.common.service.LogService;
import com.wsm.common.utils.HttpServletUtils;
import com.wsm.common.utils.Result;
import com.wsm.common.utils.ShiroUtils;
import com.wsm.system.domain.UserDO;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;


/**
 * 异常处理拦截器
 *
 * @author wsm
 * @date 2019年11月13日
 * 区分系统异常和业务异常，做不同的处理
 */
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    private static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @Autowired
    LogService logService;

    /**
     * 无权限
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({UnauthorizedException.class})
    public Object requestStackOverflow(UnauthorizedException ex, HttpServletRequest request) {
        log.error(ex.getMessage(), ex);
        if (HttpServletUtils.jsAjax(request)) {
            return Result.denyMsg("403", "未授权");
        }
        return new ModelAndView("error/403" );
    }

    /**
     * 权限认证失败
     *
     * @param e
     * @return
     */
    @ExceptionHandler(AuthorizationException.class)
    public Object handleAuthorizationException(AuthorizationException e, HttpServletRequest request) {
        log.error(e.getMessage(), e);
        if (HttpServletUtils.jsAjax(request)) {
            return Result.denyMsg("403", "未授权");
        }
        return new ModelAndView("error/403");
    }

    /**
     * 自定义异常捕获
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({MyException.class})
    public Object myException(MyException ex, HttpServletRequest request) {
        if (HttpServletUtils.jsAjax(request)) {
            return Result.denyMsg(String.valueOf(ex.getCode()), ex.getMsg());
        }
        return new ModelAndView("error/500");
    }

    /**
     * 重复提交
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(DuplicateSubmitException.class)
    public Object duplicateSubmitException(DuplicateSubmitException ex, HttpServletRequest request) {
        if (HttpServletUtils.jsAjax(request)) {
            return Result.denyMsg("402", "正在执行，请稍后");
        }
        return new ModelAndView("error/402");
    }

    /**
     * 黑名单异常
     * @param ex
     * @param request
     * @return
     */
    @ExceptionHandler(LimitAcountException.class)
    public Object limitAccouontException(LimitAcountException ex, HttpServletRequest request) {
        if (HttpServletUtils.jsAjax(request)) {
            return Result.denyMsg("400", "网站限制您的登录，请联系管理员");
        }
        return new ModelAndView("error/400");
    }
    /**
     * 其他错误
     *
     * @param e
     * @return
     */

    @ExceptionHandler({Exception.class})
    public Object handleException(Exception e, HttpServletRequest request) {
        LogDO logDO = new LogDO();
        logDO.setGmtCreate(new Date());
        logDO.setOperation(Constant.LOG_ERROR);
        logDO.setMethod(request.getRequestURL().toString());
        logDO.setParams(e.toString());
        UserDO current = ShiroUtils.getUser();
        if (null != current) {
            logDO.setUserId(current.getUserId());
            logDO.setUsername(current.getUsername());
        }
        logService.save(logDO);
        log.error(e.getMessage(), e);
        if (HttpServletUtils.jsAjax(request)) {
            return Result.error("500", "服务器错误，请联系管理员");
        }
        return new ModelAndView("error/500");
    }
}
